<!-- src/components/时空演化可视化/Manageshieldarea.vue -->
<template>
  <el-dialog class="manage-shield-area-dialog" v-model="visible" title="屏蔽区域管理" width="800px"
    :close-on-click-modal="false" @closed="handleDialogClosed" @open="handleDialogOpen">
    <!-- 屏蔽区域列表 -->
    <el-card class="list-card" shadow="never">
      <template #header>
        <div class="card-header">
          <span class="header-title">屏蔽区域列表</span>
          <span class="header-info">
            共 {{ shieldList.length }} 个区域
          </span>
        </div>
      </template>
      <el-table ref="tableRef" v-loading="loading" :data="shieldList" style="width: 100%" height="400" empty-text="暂无屏蔽区域数据">
        <el-table-column type="index" label="序号" width="60" align="center" />
        <el-table-column prop="name" label="区域名称" min-width="150" show-overflow-tooltip />
        <el-table-column prop="point_count" label="顶点数量" width="80" align="center">
          <template #default="scope">
            <el-tag v-if="getPointCount(scope.row)" :type="getPointCountTagType(scope.row)" size="small"
              class="point-count-tag">
              {{ getPointCount(scope.row) }} 点
            </el-tag>
            <span v-else class="no-data">-</span>
          </template>
        </el-table-column>
        <el-table-column label="启用状态" width="80" align="center">
          <template #default="scope">
            <el-switch v-model="scope.row.is_active" @change="toggleShieldArea(scope.row)" :active-value="true"
              :inactive-value="false" />
          </template>
        </el-table-column>
        <el-table-column label="显示状态" width="80" align="center">
          <template #default="scope">
            <el-switch v-model="scope.row.is_visible" @change="toggleVisibility(scope.row)" :active-value="true"
              :inactive-value="false" />
          </template>
        </el-table-column>
        <el-table-column label="创建时间" width="140" align="center">
          <template #default="scope">
            <div class="time-cell">
              <div class="time-date">{{ formatDate(scope.row.created_at) }}</div>
              <div class="time-time">{{ formatTime(scope.row.created_at) }}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="60" align="center" fixed="right">
          <template #default="scope">
            <el-button link type="danger" size="small" @click="handleSingleDelete(scope.row)"
              :icon="Delete">删除</el-button>
          </template>
        </el-table-column>
        <!-- 在表格列中添加选中状态 -->
        <el-table-column label="选中状态" width="80" align="center" v-if="selectedShieldAreaId">
          <template #default="scope">
            <el-icon v-if="scope.row.id.toString() === selectedShieldAreaId" color="#67C23A" :size="20">
              <Select />
            </el-icon>
            <span v-else>-</span>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 新增/编辑对话框 -->
    <el-dialog class="shield-area-edit-dialog" v-model="editDialogVisible" :title="isEditing ? '编辑屏蔽区域' : '新增屏蔽区域'"
      width="500px" append-to-body :close-on-click-modal="false" @closed="handleEditDialogClosed">
      <el-form :model="form" :rules="formRules" ref="formRef" label-width="100px" label-position="left">
        <el-form-item label="区域名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入屏蔽区域名称" maxlength="50" show-word-limit clearable />
        </el-form-item>
        <el-form-item label="区域描述" prop="description">
          <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入区域描述信息（可选）" maxlength="200"
            show-word-limit resize="none" />
        </el-form-item>
        <el-form-item label="启用状态">
          <el-switch v-model="form.is_active" active-text="启用" inactive-text="禁用" />
        </el-form-item>
        <el-form-item label="显示状态">
          <el-switch v-model="form.is_visible" active-text="显示" inactive-text="隐藏" />
        </el-form-item>
        <el-form-item label="绘制方式">
          <el-radio-group v-model="drawMethod">
            <el-radio label="manual">手动输入坐标</el-radio>
            <el-radio label="drawing">绘图区绘制</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- 手动输入 -->
        <el-form-item v-if="drawMethod === 'manual'" label="坐标点">
          <div class="coordinates-input">
            <el-button type="primary" text @click="addCoordinate" :icon="Plus" size="small">添加坐标点</el-button>
            <div class="coordinates-tip">
              <el-text v-if="!isFormValid" type="warning" size="small" style="display: block; margin-top: 4px;">
                {{ validationMessage }}
              </el-text>
            </div>
            <div v-if="form.coordinates.length" class="coordinates-list">
              <div v-for="(coord, index) in form.coordinates" :key="index" class="coordinate-item">
                <div class="coordinate-index">点 {{ index + 1 }}</div>
                <el-input-number v-model="coord.x" placeholder="X坐标" :precision="2" :step="0.01"
                  controls-position="right" size="small" @change="handleCoordinateChange"
                  :class="{ 'invalid-coord': coord.x === null || coord.x === undefined }" />
                <el-input-number v-model="coord.y" placeholder="Y坐标" :precision="2" :step="0.01"
                  controls-position="right" size="small" @change="handleCoordinateChange"
                  :class="{ 'invalid-coord': coord.y === null || coord.y === undefined }" />
                <el-input-number v-model="coord.z" placeholder="Z坐标" :precision="2" :step="0.01"
                  controls-position="right" size="small" @change="handleCoordinateChange"
                  :class="{ 'invalid-coord': coord.z === null || coord.z === undefined }" />
                <el-button type="danger" text :icon="Close" @click="removeCoordinate(index)" size="small"
                  :disabled="form.coordinates.length <= 3" />
              </div>
            </div>
            <div v-else class="empty-coordinates">
              <el-text type="info" size="small">暂无坐标点，请先添加坐标点</el-text>
            </div>
          </div>
        </el-form-item>
        <!-- 绘图区绘制 -->
        <el-form-item v-else label="绘图区绘制">
          <el-alert title="绘制说明" type="info" :closable="false"
            description="点击'开始绘制'按钮后，对话框将隐藏，鼠标变为十字形状。在绘图区依次点击多边形的各个顶点，右键结束绘制" show-icon />
          <div class="draw-action">
            <el-button type="primary" @click="startDrawing" :icon="MapLocation" :disabled="isDrawing">
              {{ isDrawing ? '绘制中...' : '开始绘制' }}
            </el-button>
            <el-button @click="clearDrawing" :disabled="!isDrawing && form.coordinates.length === 0">
              清除绘制
            </el-button>
          </div>
          <div v-if="form.coordinates.length" class="drawing-preview">
            <el-text type="success">已绘制 {{ form.coordinates.length }} 个坐标点</el-text>
            <div class="coordinates-preview">
              <div v-for="(coord, index) in form.coordinates" :key="index" class="preview-item">
                <span class="preview-index">点{{ index + 1 }}</span>
                <span class="preview-coord">({{ coord.x?.toFixed(2) }}, {{ coord.y?.toFixed(2) }}, {{
                  coord.z?.toFixed(2)
                }})</span>
              </div>
            </div>
          </div>
        </el-form-item>
        <!-- 表单验证状态提示 -->
        <el-form-item v-if="!isFormValid" class="validation-tip">
          <el-alert :title="validationMessage" type="warning" :closable="false" show-icon />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm" :loading="submitting" :disabled="!isFormValid">
          {{ isEditing ? '更新' : '保存' }}
        </el-button>
      </template>
    </el-dialog>
    <!-- 底部操作按钮 -->
    <template #footer>
      <div class="dialog-footer">
        <div class="footer-left">
          <el-text type="info">共 {{ shieldList.length }} 个屏蔽区域</el-text>
        </div>
        <div class="footer-right">
          <el-button type="primary" @click="handleAdd" :icon="Plus">
            新增屏蔽区域
          </el-button>
          <el-button @click="visible = false">关闭</el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>
<!-- src/components/时空演化可视化/Manageshieldarea.vue -->
<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick, onUnmounted, type Ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { Plus, Delete, View, Close, MapLocation ,Select} from '@element-plus/icons-vue'
import { PolygonDrawer3D, type PolygonPoint } from './PolygonDrawer3D'

// ==================== 关键类型定义 ====================

// 坐标点类型
interface CoordinatePoint {
  x: number | null
  y: number | null
  z: number | null
}
// 坐标偏移常量
const COORDINATE_OFFSET = {
  x: 2372256.14,
  y: 773022,
  z: 0
}

// 屏蔽区域数据类型
interface ShieldArea {
  id: number
  name: string
  description: string
  is_active: boolean
  is_visible: boolean  // 添加这个属性
  geom?: {
    coordinates: number[][][][]
  }
  coordinates?: CoordinatePoint[]
  point_count?: number
  created_at?: string
  updated_at?: string
}

// Three.js 环境类型
interface ThreeEnvironment {
  scene?: THREE.Scene | null
  camera?: THREE.PerspectiveCamera | null
  renderer?: THREE.WebGLRenderer | null
  domElement?: HTMLCanvasElement | null
}

// PolygonDrawer3D 实例类型
let polygonDrawer: PolygonDrawer3D | null = null
let originalBodyPointerEvents: string;
let hiddenDialogSelectors: string[] = [];

// ==================== 组件属性 ====================
const props = defineProps<{
  modelValue?: boolean
  threeScene?: THREE.Scene | null
  threeCamera?: THREE.PerspectiveCamera | null
  threeRenderer?: THREE.WebGLRenderer | null
  threeDomElement?: HTMLCanvasElement | null
  modelCenter?: { x: number; y: number; z: number }
  scaleFactor?: number
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'show-polygons', list: ShieldArea[]): void
  (e: 'start-drawing'): void
  (e: 'stop-drawing'): void
}>()

// ==================== 状态定义 ====================
const visible = ref(false)
const loading = ref(false)
const submitting = ref(false)
const editDialogVisible = ref(false)
const isEditing = ref(false)
const drawMethod = ref<'manual' | 'drawing'>('drawing')
const isDrawing = ref(false)
const shieldList = ref<ShieldArea[]>([])
const formRef = ref()
const visiblePolygons = ref<Map<number, THREE.Mesh>>(new Map())
// 选中的屏蔽区域ID
const selectedShieldAreaId = ref<string>('');
const tableRef = ref();

// 表单数据
const form = reactive<{
  id: number | null
  name: string
  description: string
  is_active: boolean
  is_visible: boolean  // 新增字段
  coordinates: CoordinatePoint[]
}>({
  id: null,
  name: '',
  description: '',
  is_active: true,
  is_visible: true,  // 默认显示
  coordinates: []
})

// 表单验证规则
const formRules = {
  name: [
    { required: true, message: '请输入屏蔽区域名称', trigger: 'blur' }
  ],
  coordinates: [
    {
      validator: (rule: any, value: CoordinatePoint[], callback: any) => {
        if (value.length < 3) {
          callback(new Error('至少需要3个坐标点'))
        } else if (!value.every(coord =>
          coord.x !== null && coord.y !== null && coord.z !== null
        )) {
          callback(new Error('所有坐标点必须完整'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ]
}

// ==================== 计算属性 ====================
const isFormValid = computed(() => {
  // 名称必填
  if (!form.name.trim()) return false

  // 坐标点验证
  if (form.coordinates.length < 3) return false

  // 每个坐标点必须完整
  const allCoordinatesValid = form.coordinates.every(coord => {
    return coord.x !== null && coord.x !== undefined &&
      coord.y !== null && coord.y !== undefined &&
      coord.z !== null && coord.z !== undefined
  })

  return allCoordinatesValid
})
const validationMessage = computed(() => {
  if (!form.name.trim()) return '请输入屏蔽区域名称'
  if (form.coordinates.length < 3) return `需要至少3个坐标点，当前只有 ${form.coordinates.length} 个`

  // 检查坐标点完整性
  const invalidCoordIndex = form.coordinates.findIndex(coord => {
    return coord.x === null || coord.x === undefined ||
      coord.y === null || coord.y === undefined ||
      coord.z === null || coord.z === undefined
  })

  if (invalidCoordIndex !== -1) {
    return `第 ${invalidCoordIndex + 1} 个坐标点数据不完整`
  }

  return '表单验证通过'
})

// 监听 dialog 状态
watch(() => props.modelValue, (val) => {
  visible.value = val
})

watch(visible, (val) => emit('update:modelValue', val))

// 添加内部状态存储 Three.js 环境
const internalThreeEnv = reactive<ThreeEnvironment>({
  scene: null,
  camera: null,
  renderer: null,
  domElement: null
})

// 修改环境检查，优先使用内部状态
const isThreeJSReady = computed(() => {
  // 优先使用内部状态，如果内部状态为空则使用 props
  const scene = internalThreeEnv.scene || props.threeScene
  const camera = internalThreeEnv.camera || props.threeCamera
  const renderer = internalThreeEnv.renderer || props.threeRenderer
  const domElement = internalThreeEnv.domElement || props.threeDomElement

  const sceneReady = scene && scene instanceof THREE.Scene
  const cameraReady = camera && camera instanceof THREE.PerspectiveCamera
  const rendererReady = renderer && renderer instanceof THREE.WebGLRenderer
  const domElementReady = domElement instanceof HTMLCanvasElement

  const ready = sceneReady && cameraReady && rendererReady && domElementReady

  console.log('环境检查结果:', {
    ready,
    scene: sceneReady,
    camera: cameraReady,
    renderer: rendererReady,
    domElement: domElementReady,
    source: {
      scene: internalThreeEnv.scene ? 'internal' : 'props',
      camera: internalThreeEnv.camera ? 'internal' : 'props',
      renderer: internalThreeEnv.renderer ? 'internal' : 'props',
      domElement: internalThreeEnv.domElement ? 'internal' : 'props'
    }
  })

  return ready
})

// 获取当前使用的 Three.js 对象
const getCurrentThreeEnv = () => {
  return {
    scene: internalThreeEnv.scene || props.threeScene,
    camera: internalThreeEnv.camera || props.threeCamera,
    renderer: internalThreeEnv.renderer || props.threeRenderer,
    domElement: internalThreeEnv.domElement || props.threeDomElement
  }
}

// 对话框打开事件
const handleDialogOpen = () => {
  console.log('对话框打开，自动加载屏蔽区域列表')
  fetchShieldAreas()
}

const coordinatesToGeoJSON = (coordinates: CoordinatePoint[]) => {
  if (coordinates.length < 3) {
    throw new Error('至少需要3个坐标点才能构成多边形')
  }

  console.log('转换前的顶点坐标（局部坐标）:', coordinates)

  const originalCoordinates = coordinates.map(coord => ({
    x: (coord.x || 0) + COORDINATE_OFFSET.x,
    y: (coord.y || 0) + COORDINATE_OFFSET.y,
    z: (coord.z || 0) + COORDINATE_OFFSET.z
  }))

  const closedCoordinates = [...originalCoordinates]
  const firstPoint = closedCoordinates[0]
  const lastPoint = closedCoordinates[closedCoordinates.length - 1]

  if (firstPoint.x !== lastPoint.x || firstPoint.y !== lastPoint.y || firstPoint.z !== lastPoint.z) {
    closedCoordinates.push({ ...firstPoint })
  }

  const geoJSON = {
    type: "MultiPolygon",
    coordinates: [
      [
        closedCoordinates.map(coord => [Number(coord.x), Number(coord.y)])
      ]
    ]
  }

  console.log('生成的GeoJSON:', geoJSON)
  return geoJSON
}


// 从GeoJSON解析坐标数组 - 应用坐标偏移到原点附近
const geoJSONToCoordinates = (geoJSON: any): CoordinatePoint[] => {
  if (!geoJSON || !geoJSON.coordinates) {
    console.warn('GeoJSON数据为空或格式不正确')
    return []
  }

  try {
    // 处理不同的GeoJSON格式
    let coordinates: number[][] = []

    if (geoJSON.type === 'MultiPolygon' && Array.isArray(geoJSON.coordinates)) {
      // MultiPolygon格式: [[[x,y], [x,y], ...]]
      if (geoJSON.coordinates[0] && Array.isArray(geoJSON.coordinates[0][0])) {
        coordinates = geoJSON.coordinates[0][0]
      }
    } else if (geoJSON.type === 'Polygon' && Array.isArray(geoJSON.coordinates)) {
      // Polygon格式: [[[x,y], [x,y], ...]]
      if (geoJSON.coordinates[0] && Array.isArray(geoJSON.coordinates[0])) {
        coordinates = geoJSON.coordinates[0]
      }
    } else if (Array.isArray(geoJSON.coordinates) && Array.isArray(geoJSON.coordinates[0])) {
      // 直接坐标数组格式
      coordinates = geoJSON.coordinates[0]
    } else {
      console.warn('不支持的GeoJSON格式:', geoJSON.type)
      return []
    }

    // 验证坐标数据
    if (!coordinates.length) {
      console.warn('坐标数据为空')
      return []
    }

    // 转换为CoordinatePoint数组，并应用坐标偏移到原点附近
    const result: CoordinatePoint[] = coordinates.map((coord: number[], index: number) => {
      // 处理可能的二维或三维坐标
      const originalX = coord[0] !== undefined ? parseFloat(coord[0].toString()) : 0
      const originalY = coord[1] !== undefined ? parseFloat(coord[1].toString()) : 0
      const originalZ = coord[2] !== undefined ? parseFloat(coord[2].toString()) : 0

      // 将原始坐标平移到原点附近（与监测点保持一致）
      const x = originalX - COORDINATE_OFFSET.x
      const y = originalY - COORDINATE_OFFSET.y
      const z = originalZ - COORDINATE_OFFSET.z

      return { x, y, z }
    }).filter(coord =>
      // 过滤掉无效坐标
      !isNaN(coord.x) && !isNaN(coord.y) && !isNaN(coord.z)
    )

    console.log(`成功解析 ${result.length} 个坐标点（已应用坐标偏移）`)
    return result

  } catch (error) {
    console.error('解析GeoJSON失败:', error)
    return []
  }
}
// 计算顶点数量
const getPointCount = (row: ShieldArea) => {
  if (row.point_count !== undefined && row.point_count !== null) {
    return row.point_count
  }

  if (row.geom && row.geom.coordinates) {
    try {
      const coordinates = row.geom.coordinates[0][0]
      return coordinates.length
    } catch (error) {
      console.error('从geom解析坐标失败:', error)
    }
  }

  if (row.coordinates && Array.isArray(row.coordinates)) {
    return row.coordinates.length
  }

  return 0
}

// 顶点数量标签样式选择
const getPointCountTagType = (row: ShieldArea) => {
  const pointCount = getPointCount(row)
  if (pointCount <= 3) {
    return 'danger' // 红色，表示顶点数量较少
  } else if (pointCount <= 6) {
    return 'warning' // 橙色
  } else if (pointCount <= 10) {
    return 'primary' // 蓝色
  } else {
    return 'success' // 绿色
  }
}

// 渲染多边形到场景
const renderPolygon = (coordinates: CoordinatePoint[], id: number, name: string) => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  // 清理已存在的同名多边形
  const existingPolygon = currentEnv.scene.getObjectByName(`shield_area_${id}`);
  if (existingPolygon) {
    currentEnv.scene.remove(existingPolygon);
    cleanupMesh(existingPolygon as THREE.Mesh);
    visiblePolygons.value.delete(id);
  }

  try {

    // 计算多边形的平均高度
    const avgZ = coordinates.reduce((sum, point) => sum + (point.z || 0), 0) / coordinates.length;

    // 或者使用第一个点的高度
    const baseZ = coordinates[0]?.z || 0;

    // 创建多边形形状
    const shape = new THREE.Shape();

    // 添加点到形状
    coordinates.forEach((point, index) => {
      if (index === 0) {
        shape.moveTo(point.x!, point.y!);
      } else {
        shape.lineTo(point.x!, point.y!);
      }
    });

    // 闭合多边形
    shape.lineTo(coordinates[0].x!, coordinates[0].y!);

    // 创建挤压几何体
    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 10,
      bevelEnabled: false
    });

    // 创建材质 - 半透明红色
    const material = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      transparent: true,
      opacity: 0.3,
      side: THREE.DoubleSide
    });

    // 创建网格
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.z = baseZ; // 使用第一个点的z坐标
    // 或者使用平均高度: mesh.position.z = avgZ;
    mesh.name = `shield_area_${id}`;
    mesh.userData = {
      shieldAreaId: id,
      name: name,
      baseHeight: baseZ,
      averageHeight: avgZ
    };

    // 添加到场景
    currentEnv.scene.add(mesh);

    // 存储引用
    visiblePolygons.value.set(id, mesh);

    console.log(`多边形 ${name} (ID: ${id}) 已渲染到场景`);

  } catch (error) {
    console.error('渲染多边形失败:', error);
  }
}

// 清理网格资源
const cleanupMesh = (mesh: THREE.Mesh) => {
  if (mesh.geometry) {
    mesh.geometry.dispose();
  }
  if (mesh.material) {
    if (Array.isArray(mesh.material)) {
      mesh.material.forEach(material => material.dispose());
    } else {
      mesh.material.dispose();
    }
  }
}

// 更新多边形显示状态（只控制视觉显示，不影响监测点过滤）
const updatePolygonVisibility = (id: number, isVisible: boolean) => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  const polygon = currentEnv.scene.getObjectByName(`shield_area_${id}`);
  if (polygon) {
    polygon.visible = isVisible;
    console.log(`多边形 ${id} 显示状态: ${isVisible ? '显示' : '隐藏'}`);
  }
}

// 从场景中移除多边形
const removePolygonFromScene = (id: number) => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  const polygon = currentEnv.scene.getObjectByName(`shield_area_${id}`);
  if (polygon) {
    currentEnv.scene.remove(polygon);

    // 清理资源
    if (polygon instanceof THREE.Mesh) {
      cleanupMesh(polygon);
    }

    // 从可见多边形映射中移除
    visiblePolygons.value.delete(id);

    console.log(`已从场景中移除屏蔽区域 ${id}`);
  }
}

// 自动滚动到选中行
const scrollToSelectedRow = () => {
  if (!selectedShieldAreaId.value || !tableRef.value) return;
  
  nextTick(() => {
    const index = shieldList.value.findIndex(area => area.id.toString() === selectedShieldAreaId.value);
    if (index !== -1) {
      // 使用 Element Plus 表格的滚动方法
      tableRef.value.setScrollTop(index * 40); // 假设每行高度为40px
      console.log(`已滚动到第 ${index + 1} 行`);
    }
  });
}

// 加载屏蔽区列表
const fetchShieldAreas = async () => {
  loading.value = true
  try {
    const res = await axios.get('/shieldareas/')
    shieldList.value = res.data || []
    
    updatePolygonsFromList()
    
    // 通知父组件重新过滤监测点
    const activeAreas = shieldList.value.filter(area => area.is_active)
    emit('show-polygons', activeAreas)
    
    // 滚动到选中行
    if (selectedShieldAreaId.value) {
      scrollToSelectedRow();
    }
    
  } catch (error) {
    console.error('加载屏蔽区域失败:', error)
    ElMessage.error('加载屏蔽区域数据失败')
    shieldList.value = []
  } finally {
    loading.value = false
  }
}
// 根据列表更新多边形（保持现有显示状态）
const updatePolygonsFromList = () => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  // 获取当前场景中已有的多边形ID
  const existingPolygonIds = new Set<number>();
  currentEnv.scene.traverse((child) => {
    if (child.name && child.name.startsWith('shield_area_')) {
      const id = parseInt(child.name.replace('shield_area_', ''));
      if (!isNaN(id)) {
        existingPolygonIds.add(id);
      }
    }
  });

  // 处理每个屏蔽区域
  shieldList.value.forEach(area => {
    if (area.coordinates && area.coordinates.length >= 3) {
      if (existingPolygonIds.has(area.id)) {
        // 多边形已存在，只更新显示状态
        updatePolygonVisibility(area.id, area.is_visible);
      } else {
        // 多边形不存在，创建新的
        renderPolygon(area.coordinates, area.id, area.name);
        // 设置显示状态
        updatePolygonVisibility(area.id, area.is_visible);
      }
    }
  });

  // 移除列表中不存在的多边形
  existingPolygonIds.forEach(id => {
    const existsInList = shieldList.value.some(area => area.id === id);
    if (!existsInList) {
      removePolygonFromScene(id);
    }
  });
}
// 新增或更新屏蔽区
// 修改提交表单函数
const submitForm = async () => {
  // 使用计算属性进行验证
  if (!isFormValid.value) {
    ElMessage.warning(validationMessage.value)
    return
  }

  submitting.value = true
  try {
    // 准备坐标数据
    let coordinatesToSave: CoordinatePoint[] = []

    if (drawMethod.value === 'manual') {
      // 手动输入模式：使用 x/y/z
      coordinatesToSave = form.coordinates
    } else {
      // 绘图模式：使用 x/y/z
      coordinatesToSave = form.coordinates
    }

    // 验证坐标数据
    if (coordinatesToSave.length < 3) {
      throw new Error('至少需要3个坐标点')
    }

    const invalidCoord = coordinatesToSave.find(coord =>
      coord.x === null || coord.y === null || coord.z === null
    )
    if (invalidCoord) {
      throw new Error('存在无效的坐标点')
    }

    // 这里会自动应用坐标偏移
    const geoJSON = coordinatesToGeoJSON(coordinatesToSave)
    const payload = {
      name: form.name,
      description: form.description,
      is_active: form.is_active,
      is_visible: form.is_visible,
      geom: JSON.stringify(geoJSON)
    }

    let response
    if (isEditing.value && form.id) {
      response = await axios.put(`/shieldareas/${form.id}/`, payload)
      ElMessage.success('更新成功')
    } else {
      response = await axios.post('/shieldareas/', payload)
      ElMessage.success('新增成功')
    }

    // 保存成功后清理预览
    clearPreviewPolygon()

    // 如果设置为显示，则渲染多边形（使用原点附近的坐标）
    if (form.is_visible) {
      renderPolygon(coordinatesToSave, response.data.id, form.name)
    }

    editDialogVisible.value = false
    fetchShieldAreas()

  } catch (err: any) {
    console.error('保存失败:', err)
    const errorMsg = err.response?.data?.error ||
      err.response?.data?.detail ||
      err.response?.data?.message ||
      err.message ||
      '保存失败'
    ElMessage.error(errorMsg)
  } finally {
    submitting.value = false
  }
}

// 清理预览多边形
const clearPreviewPolygon = () => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  const previewObject = currentEnv.scene.getObjectByName('shield_area_preview');
  if (previewObject) {
    currentEnv.scene.remove(previewObject);

    // 清理几何体和材质
    if (previewObject instanceof THREE.Mesh) {
      previewObject.geometry.dispose();
      if (Array.isArray(previewObject.material)) {
        previewObject.material.forEach(material => material.dispose());
      } else {
        previewObject.material.dispose();
      }
    }

    console.log('已清理预览多边形');
  }
}

// 预览多边形函数（如果还没有的话）
const previewPolygon = (coordinates: CoordinatePoint[]) => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  // 清理之前的预览多边形
  clearPreviewPolygon();

  try {

    // 计算多边形的平均高度
    const avgZ = coordinates.reduce((sum, point) => sum + (point.z || 0), 0) / coordinates.length;

    // 或者使用第一个点的高度
    const baseZ = coordinates[0]?.z || 0;

    // 创建多边形形状
    const shape = new THREE.Shape();

    // 添加点到形状
    coordinates.forEach((point, index) => {
      if (index === 0) {
        shape.moveTo(point.x!, point.y!);
      } else {
        shape.lineTo(point.x!, point.y!);
      }
    });

    // 闭合多边形
    shape.lineTo(coordinates[0].x!, coordinates[0].y!);

    // 创建挤压几何体
    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 100, // 多边形高度
      bevelEnabled: false
    });

    // 创建材质 - 使用半透明红色表示屏蔽区域
    const material = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      transparent: true,
      opacity: 0.3,
      side: THREE.DoubleSide
    });

    // 创建网格
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.z = baseZ; // 使用第一个点的z坐标
    // 或者使用平均高度: mesh.position.z = avgZ;
    mesh.name = 'shield_area_preview'; // 设置名称以便清理

    // 添加到场景
    currentEnv.scene.add(mesh);

    console.log('预览多边形已添加到场景');

  } catch (error) {
    console.error('创建预览多边形失败:', error);
  }
}

// 删除屏蔽区
const handleSingleDelete = async (row: ShieldArea) => {
  try {
    await ElMessageBox.confirm(
      `确定删除屏蔽区域 "${row.name}" 吗？此操作不可恢复。`,
      '提示',
      { type: 'warning' }
    )

    await axios.delete(`/shieldareas/${row.id}/`)
    ElMessage.success('删除成功')

    // ========== 修改：从场景中移除多边形并重新过滤监测点 ==========
    removePolygonFromScene(row.id)

    // 重新加载列表
    await fetchShieldAreas()

    // 重新加载监测点（过滤屏蔽区域内的点）
    emit('show-polygons', shieldList.value.filter(area => area.is_active && area.is_visible))

  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }
}


// 切换屏蔽区域状态
const toggleShieldArea = async (row: ShieldArea) => {
  try {
    const response = await axios.patch(`/shieldareas/${row.id}/toggle/`)
    ElMessage.success('状态切换成功')

    // ========== 修改：只重新过滤监测点，不改变多边形显示 ==========
    // 重新加载监测点（过滤屏蔽区域内的点）
    emit('show-polygons', shieldList.value.filter(area => area.is_active && area.is_visible))

  } catch (error) {
    console.error('切换状态失败:', error)
    ElMessage.error('操作失败')
    row.is_active = !row.is_active // 恢复状态
  }
}
// 检查点是否在屏蔽区内
const checkPointInShieldArea = async (lng: number, lat: number) => {
  try {
    const response = await axios.post('/shieldareas/check_point/', {
      longitude: lng,
      latitude: lat
    })
    return response.data.in_shield || false
  } catch (error) {
    console.error('检查点位置失败:', error)
    return false
  }
}

// 切换显示状态
const toggleVisibility = async (row: ShieldArea) => {
  try {
    const response = await axios.patch(`/shieldareas/${row.id}/toggle_visibility/`)
    ElMessage.success(response.data.message || `已${response.data.is_visible ? '显示' : '隐藏'}多边形`)

    // ========== 修改：只更新多边形显示，不重新过滤监测点 ==========
    const isVisible = response.data.is_visible

    // 只更新场景中的多边形显示状态
    updatePolygonVisibility(row.id, isVisible)

  } catch (error) {
    console.error('切换显示状态失败:', error)
    ElMessage.error('操作失败')
    // 恢复原始状态
    row.is_visible = !row.is_visible
  }
}

// 交互逻辑部分
const handleAdd = () => {
  isEditing.value = false
  resetForm()
  editDialogVisible.value = true
}

const startDrawing = async () => {
  const currentEnv = getCurrentThreeEnv();

  console.log('开始绘制 - 使用环境:', {
    scene: !!currentEnv.scene,
    camera: !!currentEnv.camera,
    renderer: !!currentEnv.renderer,
    domElement: !!currentEnv.domElement,
    isThreeJSReady: isThreeJSReady.value
  });

  if (!isThreeJSReady.value) {
    ElMessage.error('三维环境未就绪');
    return;
  }

  // 必须是 HTMLCanvasElement
  if (!(currentEnv.domElement instanceof HTMLCanvasElement)) {
    ElMessage.error('Canvas 元素无效');
    return;
  }

  // 确保所有必需的 Three.js 对象都存在
  if (!currentEnv.scene || !currentEnv.camera || !currentEnv.renderer) {
    ElMessage.error('Three.js 环境不完整');
    return;
  }

  // 获取 OrbitControls 实例
  const controls = (currentEnv.scene as any).userData?.controls as OrbitControls | undefined;
  if (!controls) {
    console.error('未找到 OrbitControls 实例！');
    ElMessage.error('绘制工具初始化失败：未找到相机控制器');
    return;
  }

  // 保存原始状态
  originalBodyPointerEvents = document.body.style.pointerEvents;

  // 精确隐藏：只隐藏屏蔽区域相关的对话框
  hiddenDialogSelectors = [];

  // 查找并隐藏主对话框
  const mainDialog = document.querySelector('.manage-shield-area-dialog');
  if (mainDialog) {
    // 找到主对话框的直接父级overlay/wrapper
    let parentToHide = mainDialog.parentElement;
    while (parentToHide &&
      !parentToHide.classList.contains('el-overlay') &&
      !parentToHide.classList.contains('el-dialog__wrapper')) {
      parentToHide = parentToHide.parentElement;
    }

    if (parentToHide) {
      (parentToHide as HTMLElement).style.display = 'none';
      hiddenDialogSelectors.push('.manage-shield-area-dialog-parent');
      console.log('已隐藏主对话框');
    }
  }

  // 查找并隐藏编辑对话框
  const editDialog = document.querySelector('.shield-area-edit-dialog');
  if (editDialog) {
    // 找到编辑对话框的直接父级overlay/wrapper
    let parentToHide = editDialog.parentElement;
    while (parentToHide &&
      !parentToHide.classList.contains('el-overlay') &&
      !parentToHide.classList.contains('el-dialog__wrapper')) {
      parentToHide = parentToHide.parentElement;
    }

    if (parentToHide) {
      (parentToHide as HTMLElement).style.display = 'none';
      hiddenDialogSelectors.push('.shield-area-edit-dialog-parent');
      console.log('已隐藏编辑对话框');
    }
  }

  console.log('已隐藏的对话框选择器:', hiddenDialogSelectors);

  document.body.style.pointerEvents = 'none';
  currentEnv.domElement.style.pointerEvents = 'auto';

  ElMessage.info('开始绘制：左键点击添加顶点，右键结束绘制，Esc 取消');

  try {
    await nextTick();

    console.log('创建 PolygonDrawer3D 实例...');

    // 创建绘制器实例
    polygonDrawer = new PolygonDrawer3D({
      scene: currentEnv.scene,
      camera: currentEnv.camera,
      renderer: currentEnv.renderer,
      domElement: currentEnv.domElement,
      controls,
      groundZ: 100,
      callbacks: {
        onDrawingComplete: (coordinates: PolygonPoint[]) => {
          console.log('绘制完成回调触发，坐标点数量:', coordinates.length);

          // 安全恢复UI
          restoreUI();

          // 转换坐标类型
          const convertedCoordinates: CoordinatePoint[] = coordinates.map(point => ({
            x: point.x,
            y: point.y,
            z: point.z
          }));

          // 处理绘制完成
          handleDrawingComplete(convertedCoordinates);
        },
        onDrawingCancel: () => {
          console.log('绘制取消回调触发');

          // 安全恢复UI
          restoreUI();

          // 处理绘制取消
          handleDrawingCancel();
        }
      }
    });

    console.log('PolygonDrawer3D 实例创建成功，开始绘制...');
    polygonDrawer.start();

    // 设置绘制状态
    isDrawing.value = true;

    emit('start-drawing');
    ElMessage.success('绘制模式已启动，左键点击添加点，右键完成');

  } catch (error: any) {
    // 发生错误时恢复界面
    restoreUI();

    console.error('启动绘制失败:', error);
    ElMessage.error(`启动绘制失败: ${error.message || error}`);
    isDrawing.value = false;
    editDialogVisible.value = true;
    visible.value = true;
  }
};

// 修改恢复UI函数
const restoreUI = () => {
  console.log('恢复UI状态');

  // 恢复body指针事件
  document.body.style.pointerEvents = originalBodyPointerEvents || '';

  // 精确恢复之前隐藏的对话框
  if (hiddenDialogSelectors.length > 0) {
    // 恢复主对话框
    if (hiddenDialogSelectors.includes('.manage-shield-area-dialog-parent')) {
      const mainDialog = document.querySelector('.manage-shield-area-dialog');
      if (mainDialog) {
        let parent = mainDialog.parentElement;
        while (parent &&
          !parent.classList.contains('el-overlay') &&
          !parent.classList.contains('el-dialog__wrapper')) {
          parent = parent.parentElement;
        }
        if (parent) {
          (parent as HTMLElement).style.display = '';
        }
      }
    }

    // 恢复编辑对话框
    if (hiddenDialogSelectors.includes('.shield-area-edit-dialog-parent')) {
      const editDialog = document.querySelector('.shield-area-edit-dialog');
      if (editDialog) {
        let parent = editDialog.parentElement;
        while (parent &&
          !parent.classList.contains('el-overlay') &&
          !parent.classList.contains('el-dialog__wrapper')) {
          parent = parent.parentElement;
        }
        if (parent) {
          (parent as HTMLElement).style.display = '';
        }
      }
    }

    console.log('已精确恢复隐藏的对话框');
  } else {
    // 安全恢复：显示所有可能的屏蔽区域对话框
    const dialogs = document.querySelectorAll('.manage-shield-area-dialog, .shield-area-edit-dialog');
    dialogs.forEach(dialog => {
      let parent = dialog.parentElement;
      while (parent &&
        !parent.classList.contains('el-overlay') &&
        !parent.classList.contains('el-dialog__wrapper')) {
        parent = parent.parentElement;
      }
      if (parent) {
        (parent as HTMLElement).style.display = '';
      }
    });
    console.log('已安全恢复所有屏蔽区域对话框');
  }

  hiddenDialogSelectors = [];
};


// 修改处理绘制完成的函数，确保编辑对话框正确显示
const handleDrawingComplete = (coordinates: CoordinatePoint[]) => {
  console.log('绘制完成回调，坐标点数量:', coordinates?.length)

  if (coordinates && coordinates.length >= 3) {
    form.coordinates = coordinates
    ElMessage.success(`绘制完成，已添加 ${coordinates.length} 个坐标点`)

    // 确保编辑对话框显示
    editDialogVisible.value = true
    // 确保主对话框也显示（因为编辑对话框是嵌套在主对话框内的）
    visible.value = true

    console.log('设置编辑对话框可见:', editDialogVisible.value, '主对话框可见:', visible.value)
  } else {
    ElMessage.warning('绘制失败，至少需要3个点才能构成多边形')
    // 只显示主对话框
    visible.value = true
  }

  // 停止绘制器
  stopDrawing()
}

// 修改处理绘制取消的函数
const handleDrawingCancel = () => {
  console.log('绘制取消回调')

  // 停止绘制器
  stopDrawing()

  // 重新显示主对话框和编辑对话框
  editDialogVisible.value = true
  visible.value = true
  ElMessage.info('绘制已取消')

  console.log('取消后编辑对话框可见:', editDialogVisible.value, '主对话框可见:', visible.value)
}

// 停止绘制
const stopDrawing = () => {
  if (polygonDrawer) {
    polygonDrawer.stop()
    polygonDrawer = null
  }
  isDrawing.value = false
  emit('stop-drawing')
}

const clearDrawing = () => {
  form.coordinates = []
  ElMessage.info('已清除绘制')
}

// 坐标点管理（手动输入模式）
const addCoordinate = () => {
  form.coordinates.push({ x: null, y: null, z: null })
  nextTick(() => {
    const inputs = document.querySelectorAll('.coordinate-item:last-child input')
    if (inputs[0]) (inputs[0] as HTMLElement).focus()
  })
}

const removeCoordinate = (index: number) => {
  if (form.coordinates.length <= 3) {
    ElMessage.warning('至少需要3个坐标点才能构成多边形')
    return
  }
  form.coordinates.splice(index, 1)
}

// 坐标变化处理
const handleCoordinateChange = () => {
  // 这里可以添加额外的处理逻辑，如果需要的话
  console.log('坐标发生变化', form.coordinates)
}

const resetForm = () => {
  Object.assign(form, {
    id: null,
    name: '',
    description: '',
    is_active: true,
    is_visible: true,  // 重置为显示
    coordinates: []
  })
  drawMethod.value = 'drawing'
  isDrawing.value = false
}

// 在对话框关闭时清理高亮
const handleDialogClosed = () => {
  stopDrawing();
  resetForm();
  clearShieldAreaHighlight(); // 清理高亮
  selectedShieldAreaId.value = ''; // 重置选中ID
}
const handleEditDialogClosed = () => {
  stopDrawing()
}

const formatDate = (t: string) => (t ? new Date(t).toLocaleDateString('zh-CN') : '-')
const formatTime = (t: string) => (t ? new Date(t).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }) : '-')

// 修改 open 方法以支持选中区域
const open = (environment: ThreeEnvironment | null = null) => {
  console.log('打开对话框，接收到的环境:', environment)

  // 重置所有状态，确保对话框能正常打开
  stopDrawing();

  // 如果通过参数传递了环境，保存到内部状态
  if (environment) {
    internalThreeEnv.scene = environment.scene
    internalThreeEnv.camera = environment.camera
    internalThreeEnv.renderer = environment.renderer
    internalThreeEnv.domElement = environment.domElement

    // 检查是否有选中的屏蔽区域ID
    if ((environment as any).selectedShieldAreaId) {
      selectedShieldAreaId.value = (environment as any).selectedShieldAreaId;
      console.log('接收到选中的屏蔽区域ID:', selectedShieldAreaId.value);
    }

    console.log('已保存到内部状态:', {
      scene: !!internalThreeEnv.scene,
      camera: !!internalThreeEnv.camera,
      renderer: !!internalThreeEnv.renderer,
      domElement: !!internalThreeEnv.domElement,
      selectedShieldAreaId: selectedShieldAreaId.value
    })
  }

  // 确保对话框状态正确
  visible.value = true
  editDialogVisible.value = false
  isDrawing.value = false

  // 延迟检查，确保状态已更新
  nextTick(() => {
    console.log('对话框打开后环境状态:', {
      internal: {
        scene: !!internalThreeEnv.scene,
        camera: !!internalThreeEnv.camera,
        renderer: !!internalThreeEnv.renderer,
        domElement: !!internalThreeEnv.domElement
      },
      props: {
        scene: !!props.threeScene,
        camera: !!props.threeCamera,
        renderer: !!props.threeRenderer,
        domElement: !!props.threeDomElement
      },
      isThreeJSReady: isThreeJSReady.value,
      selectedShieldAreaId: selectedShieldAreaId.value
    })

    fetchShieldAreas().then(() => {
      // 如果有选中的屏蔽区域，高亮显示
      if (selectedShieldAreaId.value) {
        highlightSelectedShieldArea();
      }
    });
  })
}
// 高亮选中的屏蔽区域
const highlightSelectedShieldArea = () => {
  if (!selectedShieldAreaId.value) return;

  const shieldArea = shieldList.value.find(area => area.id.toString() === selectedShieldAreaId.value);
  if (shieldArea) {
    console.log('高亮显示选中的屏蔽区域:', shieldArea.name);

    // 可以在这里添加高亮逻辑，比如：
    // 1. 在表格中滚动到该行
    // 2. 在三维场景中特别高亮该区域
    // 3. 显示选中状态

    // 示例：在三维场景中高亮
    highlightShieldAreaInScene(shieldArea.id);
  }
}

// 在三维场景中高亮屏蔽区域
const highlightShieldAreaInScene = (shieldAreaId: number) => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  // 清除之前的高亮
  clearShieldAreaHighlight();

  const shieldAreaObject = currentEnv.scene.getObjectByName(`shield_area_${shieldAreaId}`);
  if (shieldAreaObject && shieldAreaObject instanceof THREE.Mesh) {
    // 保存原始材质
    shieldAreaObject.userData.originalMaterial = shieldAreaObject.material;

    // 应用高亮材质
    const highlightMaterial = new THREE.MeshBasicMaterial({
      color: 0x00ff00, // 绿色高亮
      transparent: true,
      opacity: 0.6,
      side: THREE.DoubleSide
    });

    shieldAreaObject.material = highlightMaterial;
    console.log(`已高亮屏蔽区域: ${shieldAreaId}`);
  }
}

// 清除屏蔽区域高亮
const clearShieldAreaHighlight = () => {
  const currentEnv = getCurrentThreeEnv();
  if (!currentEnv.scene) return;

  currentEnv.scene.traverse((child) => {
    if (child.name && child.name.startsWith('shield_area_') && child.userData.originalMaterial) {
      if (child instanceof THREE.Mesh) {
        child.material = child.userData.originalMaterial;
        delete child.userData.originalMaterial;
      }
    }
  });
}



// 修改关闭方法
const close = () => {
  stopDrawing()
  visible.value = false
}

// 组件卸载时清理
onUnmounted(() => {
  stopDrawing()
})

// 添加环境状态文本方法
const getEnvironmentStatusText = () => {
  const env = getCurrentThreeEnv()
  return `场景: ${env.scene ? '✓' : '✗'} | 相机: ${env.camera ? '✓' : '✗'} | 渲染器: ${env.renderer ? '✓' : '✗'} | Canvas: ${env.domElement ? '✓' : '✗'}`
}

defineExpose({
  open,
  close,
  fetchShieldAreas,
  checkPointInShieldArea
})
</script>

<style scoped>
/* 卡片样式 */
.list-card {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  margin-bottom: 16px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  font-weight: 600;
  color: #303133;
}

.header-info {
  font-size: 12px;
  color: #909399;
}

/* 表格样式 */
.time-cell {
  line-height: 1.3;
  font-size: 12px;
}

.time-date {
  font-size: 11px;
  color: #606266;
}

.time-time {
  font-size: 10px;
  color: #909399;
}

.no-data {
  color: #c0c4cc;
  font-style: italic;
}

.point-count-tag {
  font-weight: 500;
  min-width: 40px;
  text-align: center;
  font-size: 12px;
}

/* 优化表格列间距 */
:deep(.el-table .el-table__cell) {
  padding: 8px 4px;
}

:deep(.el-table .el-table__cell .cell) {
  padding-left: 4px;
  padding-right: 4px;
}

/* 调整开关样式 */
:deep(.el-switch) {
  transform: scale(0.8);
}

/* 标签样式 */
:deep(.el-tag) {
  border: none;
}

:deep(.el-tag.el-tag--primary) {
  background-color: #409eff;
  color: white;
}

:deep(.el-tag.el-tag--success) {
  background-color: #67c23a;
  color: white;
}

:deep(.el-tag.el-tag--warning) {
  background-color: #e6a23c;
  color: white;
}

:deep(.el-tag.el-tag--danger) {
  background-color: #f56c6c;
  color: white;
}

:deep(.el-tag.el-tag--info) {
  background-color: #909399;
  color: white;
}

/* 坐标输入样式 */
.coordinates-input {
  width: 100%;
}

.coordinates-tip {
  margin: 8px 0;
  padding: 4px 0;
}

.coordinates-list {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 300px;
  overflow-y: auto;
  padding: 12px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  background: #fafafa;
}

.coordinate-item {
  display: grid;
  grid-template-columns: 40px 1fr 1fr 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 8px;
  background: white;
  border-radius: 4px;
  border: 1px solid #f0f0f0;
}

.coordinate-index {
  font-size: 12px;
  color: #909399;
  text-align: center;
  font-weight: 500;
}

/* 无效坐标点的样式 */
.invalid-coord :deep(.el-input-number__inner) {
  border-color: #f56c6c;
  background-color: #fef0f0;
}

.invalid-coord :deep(.el-input-number__inner:focus) {
  border-color: #f56c6c;
  box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.2);
}

.coordinates-tip .el-text--warning {
  margin-top: 4px;
  display: block;
  font-weight: 500;
}

.empty-coordinates {
  padding: 20px;
  text-align: center;
  border: 1px dashed #dcdfe6;
  border-radius: 4px;
  background: #fafafa;
  color: #909399;
}

/* 绘制操作样式 */
.draw-action {
  margin-top: 12px;
  display: flex;
  gap: 12px;
}

.drawing-preview {
  margin-top: 12px;
  padding: 16px;
  background: #f0f9ff;
  border-radius: 4px;
  border: 1px solid #bae0ff;
}

.coordinates-preview {
  margin-top: 8px;
  max-height: 120px;
  overflow-y: auto;
}

.preview-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 8px;
  margin: 2px 0;
  background: white;
  border-radius: 3px;
  font-size: 12px;
  border: 1px solid #f0f0f0;
}

.preview-index {
  color: #606266;
  font-weight: 500;
  min-width: 40px;
}

.preview-coord {
  color: #909399;
  font-family: 'Courier New', monospace;
  font-size: 11px;
}

/* 验证提示样式 */
.validation-tip {
  margin-top: 16px;
}

.validation-tip :deep(.el-alert) {
  padding: 8px 16px;
}

/* 对话框底部样式 */
.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 12px 0;
  border-top: 1px solid #e4e7ed;
}

.footer-left {
  flex: 1;
  font-size: 12px;
}

.footer-right {
  display: flex;
  gap: 8px;
}

/* 操作按钮优化 */
:deep(.el-button--small) {
  padding: 5px 8px;
  font-size: 12px;
}

/* 输入框样式优化 */
:deep(.el-input-number) {
  width: 100%;
}

:deep(.el-input-number .el-input__inner) {
  text-align: center;
}

/* 表单标签样式 */
:deep(.el-form-item__label) {
  font-weight: 500;
  color: #606266;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .card-header {
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
  }

  .dialog-footer {
    flex-direction: column;
    gap: 10px;
  }

  .footer-left,
  .footer-right {
    width: 100%;
    justify-content: center;
  }

  .footer-right {
    flex-wrap: wrap;
  }

  .coordinate-item {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 12px;
  }

  .coordinate-index {
    text-align: left;
    font-weight: 600;
    color: #409eff;
    background: #f0f9ff;
    padding: 4px 8px;
    border-radius: 3px;
    margin-bottom: 4px;
  }

  .draw-action {
    flex-direction: column;
    gap: 8px;
  }

  .draw-action .el-button {
    width: 100%;
  }

  /* 表格在小屏幕下的调整 */
  :deep(.el-table) {
    font-size: 12px;
  }

  :deep(.el-table .el-table__cell) {
    padding: 4px 2px;
  }

  :deep(.el-table .el-table__cell .cell) {
    padding-left: 2px;
    padding-right: 2px;
  }

  /* 预览项在小屏幕下的调整 */
  .preview-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  .preview-index {
    min-width: auto;
  }
}

/* 滚动条样式 */
.coordinates-list::-webkit-scrollbar,
.coordinates-preview::-webkit-scrollbar {
  width: 6px;
}

.coordinates-list::-webkit-scrollbar-track,
.coordinates-preview::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.coordinates-list::-webkit-scrollbar-thumb,
.coordinates-preview::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.coordinates-list::-webkit-scrollbar-thumb:hover,
.coordinates-preview::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 动画效果 */
.coordinate-item {
  transition: all 0.3s ease;
}

.coordinate-item:hover {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transform: translateY(-1px);
}

.preview-item {
  transition: all 0.2s ease;
}

.preview-item:hover {
  background: #f5f7fa;
}

/* 操作按钮组样式 */
:deep(.el-button-group) {
  display: flex;
  gap: 1px;
}

:deep(.el-button-group .el-button) {
  border-radius: 0;
}

:deep(.el-button-group .el-button:first-child) {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}

:deep(.el-button-group .el-button:last-child) {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}

/* 表单验证状态样式 */
:deep(.el-form-item.is-error .el-input-number__inner) {
  border-color: #f56c6c;
}

:deep(.el-form-item.is-success .el-input-number__inner) {
  border-color: #67c23a;
}

/* 自定义颜色变量 */
.manage-shield-area-dialog {
  --primary-color: #409eff;
  --success-color: #67c23a;
  --warning-color: #e6a23c;
  --danger-color: #f56c6c;
  --info-color: #909399;
}

/* 对话框内容区域样式 */
:deep(.el-dialog__body) {
  padding: 20px;
}

:deep(.el-dialog__header) {
  padding: 20px 20px 10px;
  border-bottom: 1px solid #e4e7ed;
}

:deep(.el-dialog__footer) {
  padding: 10px 20px 20px;
  border-top: 1px solid #e4e7ed;
}

/* 卡片阴影和边框 */
:deep(.el-card) {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

:deep(.el-card__header) {
  padding: 12px 20px;
  background: #fafafa;
  border-bottom: 1px solid #e4e7ed;
}
</style>